package com.md.drcs.dicom.util;

import com.md.common.utils.codec.EncodeUtils;
import com.md.common.utils.json.JSONUtil;
import com.md.drcs.dicom.dto.DicomQRCodeDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class DicomQRCodeUtils {

    private static final String SECRET_KEY_SPEC = "tskjyjpxtaestskj";

    private static final Logger LOGGER = LoggerFactory.getLogger(DicomQRCodeUtils.class);

    private static Cipher cip = null;

    public static String decrypt(String data) {
        return decrypt(data, SECRET_KEY_SPEC);
    }

    public static String decrypt(String data, String keyBytes) {
        byte[] content = EncodeUtils.decodeBase64(data);
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(keyBytes.getBytes(), "AES");
            if (null == cip)
                cip = Cipher.getInstance("AES/ECB/NoPadding");
            cip.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] output = cip.doFinal(content);
            return new String(output).trim();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return null;
    }

    public static String encrypt(String data) {
        return encrypt(data, SECRET_KEY_SPEC);
    }

    public static String encrypt(String data, String keyBytes) {
        try {
            //长度必须为16的倍数
            int length = ((data.length() + 15) / 16) * 16;
            byte[] content = new byte[length];
            System.arraycopy(data.getBytes(), 0, content, 0, data.length());
            for (int i = 0; i < content.length - data.length(); i++) {
                content[data.length() + i] = 0x20;
            }
            SecretKeySpec skeySpec = new SecretKeySpec(keyBytes.getBytes(), "AES");
            if (null == cip)
                cip = Cipher.getInstance("AES/ECB/NoPadding");//
            cip.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] out = cip.doFinal(content);
            Base64.Encoder encoder = Base64.getEncoder();
            byte[] result = encoder.encode(out);
            return new String(result);
        } catch (Exception e) {
            return null;
        }
    }

    public static String genQRCode(String hospId, String hospStudyId) {
        String code = DicomQRCodeUtils.encrypt(String.format("00@@02@@%s@@%s", hospId, hospStudyId));
        if (code == null)
            return null;
        return code.replace("+", "-").replace("/", "_");
    }

    public static DicomQRCodeDTO parseQRCode(String qrCode) {
        String[] cnts = qrCode.split("code=");

        Assert.isTrue(cnts.length == 2, "非影像二维码，扫码失败");

        String source = cnts[1].replace("-", "+").replace("_", "/");
        String decrypt = decrypt(source);

        LOGGER.debug("source : {}, decrypt: {}", source, decrypt);

        Assert.notNull(decrypt, "非影像二维码，扫码失败");

        String[] contents = decrypt.split("@@");

        Assert.isTrue(contents.length >= 4, "非影像二维码，扫码失败");

        DicomQRCodeDTO dto = new DicomQRCodeDTO();

        dto.setHospitalId(contents[2]);
        dto.setHospStudyId(contents[3]);

        return dto;
    }

    public static void main(String[] args) {

        String src = "http://www.yuepianzhongxin.com/mainview/query?version=1.0&code=EHbzBKGbM0R4fIZavNEry_mSDUXntz8Kbm-IBc5QuWk=";

        DicomQRCodeDTO dto = parseQRCode(src);

        System.out.println("parsed: " + JSONUtil.toJSON(dto));

        String code = DicomQRCodeUtils.genQRCode("020002", "33856");

        System.out.println("encrypted: " + code);

        String src2 = "http://www.yuepianzhongxin.com/mainview/query?version=1.0&code=" + code;

        System.out.println("gen src: " + src2);

//        System.out.println("parsed2: " + JSONUtil.toJSON(parseQRCode(src2)));
//
//        File file = new File("D:\\images\\0756888");
//        File[] files = file.listFiles();
//        if (files == null)
//            return;
//        List<File> needDeleteFiles = Stream.of(files)
//                .sorted((f1, f2) -> (int) (f1.lastModified() - f2.lastModified()))
//                .limit(2)
//                .collect(Collectors.toList());
//
//        needDeleteFiles.forEach(e -> {
//            System.out.print(e.getPath() + "  ");
//            System.out.println(new Date(e.lastModified()));
//        });

    }

}
